package com.ltmonitor.server.netty;

import com.ltmonitor.jt808.service.IGpsConnectionService;
import io.netty.channel.Channel;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.SimpleChannelInboundHandler;
import io.netty.util.Attribute;
import io.netty.util.AttributeKey;

import java.util.Collection;
import java.util.Date;
import java.util.concurrent.ConcurrentMap;

import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.ltmonitor.app.GpsConnection;
import com.ltmonitor.jt808.protocol.JT_0200;
import com.ltmonitor.jt808.protocol.T808Message;
import com.ltmonitor.jt808.service.IMessageProcessService;
import com.ltmonitor.util.StringUtil;

/**
 *
 */
@Service("protocolServerHandler")
public class ProtocolServerHandler extends SimpleChannelInboundHandler<Object> {

	private Logger logger = Logger.getLogger(ProtocolServerHandler.class);

	private IMessageProcessService messageProcessService;

	private IGpsConnectionService gpsConnectionService;

	private static AttributeKey<String> key = AttributeKey.valueOf("simNo");
	@Override
	protected void channelRead0(ChannelHandlerContext ctx, Object obj)
			throws Exception {
		Channel incoming = ctx.channel();
		String sessionId = ctx.channel().id().asLongText();
		if (obj instanceof T808Message) {
			T808Message tm = (T808Message) obj;
			incoming.attr(key).set(tm.getSimNo());
			GpsConnection conn = this.gpsConnectionService.getConnection(0, tm);
			if (conn != null) {
				conn.setConnected(true);
				if (messageProcessService != null)
					messageProcessService.processMsg(tm);
				if (tm.getHeader() != null
						&& tm.getHeader().getMessageType() == 0x0200) {
					JT_0200 p = (JT_0200) tm.getMessageContents();
					conn.setLocated(p.isValid());
					conn.setPositionPackageNum(conn.getPositionPackageNum() + 1);
				}
				tm.setPlateNo(conn.getPlateNo());

				if (conn.getPackageNum() == Integer.MAX_VALUE) {
					conn.setPackageNum(0);
					conn.setErrorPacketNum(0);
					conn.setErrorPacketNum(0);
				}

				conn.setNettyChannel(incoming);

				conn.setPackageNum(conn.getPackageNum() + 1);

				if (tm.getErrorMessage() != null) {
					conn.setErrorPacketNum(conn.getErrorPacketNum() + 1);
				}

			}
			 //ProtocolMsg msg = (ProtocolMsg)obj;
			 //System.out.println("Client->Server:"+incoming.remoteAddress()+msg.getBody());
			 incoming.write(obj);
		}
	}

	@Override
	public void channelReadComplete(ChannelHandlerContext ctx) throws Exception {
		//logger.info("read complete");
	}

	@Override
	public void channelRegistered(ChannelHandlerContext ctx)
			throws Exception {
		//logger.info("channel register");
	}

	@Override
	public void channelUnregistered(
			ChannelHandlerContext ctx) throws Exception {
		//logger.error("channel unregister");
		String sessionId = ctx.channel().id().asLongText();
		Attribute<String> attr = ctx.channel().attr(key);
		if (attr != null) {
			String simNo = attr.get();
			if (StringUtil.isNullOrEmpty(simNo) == false) {
				this.gpsConnectionService.closeConnection(simNo);
				/**
				 GpsConnection conn = getConnctionMap().get(simNo);
				 if (conn != null) {
				 // connctionMap.remove(simNo);
				 conn.setConnected(false);
				 conn.setDisconnectTimes(conn.getDisconnectTimes() + 1);
				 logger.error(simNo + "," + conn.getPlateNo() + "断开连接");
				 }*/
			}
		}
	}

	@Override
	public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause)
			throws Exception {
		logger.error("netty连接异常:" + cause.getMessage());
	}

	@Override
	public void channelActive(ChannelHandlerContext ctx) throws Exception {
		//logger.error("==============channel-active==============");
	}

	@Override
	public void channelInactive(ChannelHandlerContext ctx) throws Exception {
		//logger.error("==============channel-inactive==============");
	}


	public IMessageProcessService getMessageProcessService() {
		return messageProcessService;
	}

	public void setMessageProcessService(IMessageProcessService messageProcessService) {
		this.messageProcessService = messageProcessService;
	}

	public IGpsConnectionService getGpsConnectionService() {
		return gpsConnectionService;
	}

	public void setGpsConnectionService(IGpsConnectionService gpsConnectionService) {
		this.gpsConnectionService = gpsConnectionService;
	}




}
